<template>
  <p>表格高度默认铺满父容器,因此父容器需要设置高度</p>
  <div style="height: 80vh; box-sizing: border-box">
    <MerakXTable
      ref="tableRef"
      :columns-by-store="generateColumns()"
      :row-height="60"
      :column-type="['index', 'multiple', 'expand', 'handle']"
      :batches="[{ type: 'delete', text: '批量删除' }]"
      :handles="[
        { type: 'details', text: '查看详情' },
        { type: 'delete', text: '删除', divided: true }
      ]"
      :batch-click="handleBatchClick"
      :handler-click="handleHanlerClick"
      :query-columns="handleQueryColumns"
      :query-options="handleQueryOptions"
      :query-data="handleQueryData"
      @config-change="handleConfigChange"
      @tool-click="handleToolClick"
    >
      <template #tools>
        <el-button @click="tableRef?.reloadData()">重新请求</el-button>
        <el-button @click="tableRef?.reloadTable()">刷新表格</el-button>
      </template>
      <template #expand="{ row }">
        <div>当前行数据: {{ JSON.stringify(row) }}</div>
      </template>
      <template #column_5_child_1_child_2_default="{ row }">
        <div class="custom_row">自定义插槽 用于折行 {{ row["column_5_child_1_child_2"] }}</div>
      </template>
    </MerakXTable>
  </div>
  <slot :html="html" />
</template>

<script setup lang="ts">
import { ref } from "vue";

import MerakXTable, { MerakXTableInstance, MerakXTableColumn } from "../../../../../components/MerakXTable";

import { ElButton } from "element-plus";

const tableRef = ref<MerakXTableInstance>();

const html = ref(`
<template>
  <div style="height: 70vh; box-sizing: border-box">
    <MerakXTable
      ref="tableRef"
      :columns-by-store="generateColumns()"
      :row-height="60"
      :column-type="['index', 'multiple', 'handle']"
      :batches="[{ type: 'delete', text: '批量删除' }]"
      :handles="[
        { type: 'details', text: '查看详情' },
        { type: 'delete', text: '删除', divided: true }
      ]"
      :batch-click="handleBatchClick"
      :handler-click="handleHanlerClick"
      :query-columns="handleQueryColumns"
      :query-options="handleQueryOptions"
      :query-data="handleQueryData"
      @config-change="handleConfigChange"
      @tool-click="handleToolClick"
    >
      <template #tools>
        <el-button @click="tableRef?.reloadData()">重新请求</el-button>
        <el-button @click="tableRef?.reloadTable()">刷新表格</el-button>
      </template>
      <template #column_5_child_1_child_2_default="{ row }">
        <div class="custom_row">自定义插槽 用于折行 {{ row["column_5_child_1_child_2"] }}</div>
      </template>
    </MerakXTable>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";

import MerakXTable, { MerakXTableInstance, MerakXTableColumn } from "../../../../../components/MerakXTable";

import { ElButton } from "element-plus";

const tableRef = ref<MerakXTableInstance>();

const generateColumns = (length: number = 80) =>
  Array.from({ length }).map((_, index) => {
    const column: MerakXTableColumn = {
      field: \`column_\${index + 1}\`,
      title: \`column_\${index + 1}\`
    };
    if (index === 0) {
      column.sortable = true;
      column.params = {
        searchType: "input"
      };
    }
    if (index === 1) {
      column.sortable = true;
      column.params = {
        searchType: "select"
      };
    }
    if (index === 2) {
      column.sortable = true;
      column.params = {
        searchType: "date"
      };
    }
    if (index === 3) {
      column.sortable = true;
      column.params = {
        searchType: "daterange"
      };
    }
    if (index === 4) {
      column.params = {
        disabled: true
      };
      column.children = [
        {
          field: \`\${column.field}_child_1\`,
          title: \`\${column.field}_child_1\`,
          children: [
            {
              field: \`\${column.field}_child_1_child_1\`,
              title: \`\${column.field}_child_1_child_1\`,
              params: { searchType: "input" }
            },
            { field: \`\${column.field}_child_1_child_2\`, title: \`\${column.field}_child_1_child_2\`, sortable: true }
          ]
        },
        { field: \`\${column.field}_child_2\`, title: \`\${column.field}_child_2\`, params: { summary: 200, summarySpan: 2 } },
        { field: \`\${column.field}_child_3\`, title: \`\${column.field}_child_3\` }
      ];
    }
    if (index === 5) {
      column.visible = false;
      column.params = {
        disabled: true
      };
    }
    return column;
  });

const recursion = (id: string, columns: MerakXTableColumn[]) => {
  const record: Record<string, any> = {};
  for (let column of columns) {
    if (!!column.field) {
      record[column.field] = \`\${column.field} \${id}\`;
    }
    if (!!column.children?.length) {
      Object.assign(record, recursion(id, column.children));
    }
  }
  return record;
};

const generateData = (length: number = 10000) =>
  Array.from({ length }).map((_, index) => {
    const payload: Record<string, any> = {
      id: \`row_\${index + 1}\`
    };
    if (index === 0) {
      payload.hasChild = true;
    }
    return { ...payload, ...recursion(payload.id, generateColumns()) };
  });

const handleQueryColumns: MerakXTableInstance["queryColumns"] = () => {
  const recursionGenerateSlots = (columns: MerakXTableColumn[]) => {
    const cols: MerakXTableColumn[] = [];
    for (let column of columns) {
      if (column.field === "column_5_child_1_child_2") {
        column.width = 200;
        column.slots = { default: "column_5_child_1_child_2_default" };
      }
      if (!!column.children?.length) {
        column.children = recursionGenerateSlots(column.children);
      }
      cols.push(column);
    }
    return cols;
  };
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        pageSize: 100,
        columns: recursionGenerateSlots(generateColumns())
      });
    }, 500);
  });
};

const handleQueryOptions: MerakXTableInstance["queryOptions"] = field => {
  console.log(field);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([
        { value: "a", label: "选项A" },
        { value: "b", label: "选项B" },
        { value: "c", label: "选项C" }
      ]);
    }, 500);
  });
};

const handleQueryData: MerakXTableInstance["queryData"] = params => {
  let start: number = 0,
    end: number = 0;
  const { page, sorts, filters, from } = params;
  console.log(page, sorts, filters, from);
  if (!!page) {
    const { currentPage, pageSize } = page;
    start = (currentPage - 1) * pageSize;
    end = start + pageSize;
  }
  const data = generateData().slice(start, end);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        total: 10000,
        currentPage: params.page?.currentPage ?? 1,
        list: data
      });
    }, 1000);
  });
};

const handleConfigChange: MerakXTableInstance["onConfig-change"] = ({ pageSize, columns }) => {
  console.log(pageSize, columns);
};

const handleToolClick: MerakXTableInstance["onTool-click"] = type => {
  console.log(type);
};

const handleBatchClick: MerakXTableInstance["batchClick"] = async arg => {
  console.log(arg);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        refresh: true
      });
    }, 500);
  });
};

const handleHanlerClick: MerakXTableInstance["handlerClick"] = async params => {
  console.log(params);
  if (params.type === 'details') return false
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({});
    }, 500);
  });
};
<\/script>

<style scoped lang="scss">
.custom_row {
  word-wrap: break-word;
  white-space: wrap;
}
</style>
`);

const generateColumns = (length: number = 80) =>
  Array.from({ length }).map((_, index) => {
    const column: MerakXTableColumn = {
      field: `column_${index + 1}`,
      title: `column_${index + 1}`
    };
    if (index === 0) {
      column.sortable = true;
      column.params = {
        searchType: "input"
      };
    }
    if (index === 1) {
      column.sortable = true;
      column.params = {
        searchType: "select",
        searchValue: "a",
        searchDefaultValue: "选项A"
      };
    }
    if (index === 2) {
      column.sortable = true;
      column.params = {
        searchType: "date"
      };
    }
    if (index === 3) {
      column.sortable = true;
      column.params = {
        searchType: "daterange"
      };
    }
    if (index === 4) {
      column.params = {
        disabled: true
      };
      column.children = [
        {
          field: `${column.field}_child_1`,
          title: `${column.field}_child_1`,
          children: [
            {
              field: `${column.field}_child_1_child_1`,
              title: `${column.field}_child_1_child_1`,
            },
            { field: `${column.field}_child_1_child_2`, title: `${column.field}_child_1_child_2`, sortable: true }
          ]
        },
        { field: `${column.field}_child_2`, title: `${column.field}_child_2`, params: { summary: 200, summarySpan: 2 } },
        { field: `${column.field}_child_3`, title: `${column.field}_child_3` }
      ];
    }
    if (index === 5) {
      column.visible = false;
      column.params = {
        disabled: true
      };
    }
    return column;
  });

const recursion = (id: string, columns: MerakXTableColumn[]) => {
  const record: Record<string, any> = {};
  for (let column of columns) {
    if (!!column.field) {
      record[column.field] = `${column.field} ${id}`;
    }
    if (!!column.children?.length) {
      Object.assign(record, recursion(id, column.children));
    }
  }
  return record;
};

const generateData = (length: number = 10000) =>
  Array.from({ length }).map((_, index) => {
    const payload: Record<string, any> = {
      id: `row_${index + 1}`
    };
    if (index === 0) {
      payload.hasChild = true;
    }
    return { ...payload, ...recursion(payload.id, generateColumns()) };
  });

const handleQueryColumns: MerakXTableInstance["queryColumns"] = () => {
  const recursionGenerateSlots = (columns: MerakXTableColumn[]) => {
    const cols: MerakXTableColumn[] = [];
    for (let column of columns) {
      if (column.field === "column_5_child_1_child_2") {
        column.width = 200;
        column.slots = { default: "column_5_child_1_child_2_default" };
      }
      if (!!column.children?.length) {
        column.children = recursionGenerateSlots(column.children);
      }
      cols.push(column);
    }
    return cols;
  };
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        table_id: "test",
        version: 1,
        pageSize: 100,
        columns: recursionGenerateSlots(generateColumns())
      });
    }, 500);
  });
};

const handleQueryOptions: MerakXTableInstance["queryOptions"] = field => {
  console.log(field);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([
        { value: "a", label: "选项A" },
        { value: "b", label: "选项B" },
        { value: "c", label: "选项C" }
      ]);
    }, 500);
  });
};

const handleQueryData: MerakXTableInstance["queryData"] = params => {
  let start: number = 0,
    end: number = 0;
  const { page, sorts, filters, from } = params;
  console.log(page, sorts, filters, from);
  if (!!page) {
    const { currentPage, pageSize } = page;
    start = (currentPage - 1) * pageSize;
    end = start + pageSize;
  }
  const data = generateData().slice(start, end);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        total: 10000,
        currentPage: params.page?.currentPage ?? 1,
        list: data
      });
    }, 1000);
  });
};

const handleConfigChange: MerakXTableInstance["onConfig-change"] = ({ pageSize, columns }) => {
  console.log(pageSize, columns);
};

const handleToolClick: MerakXTableInstance["onTool-click"] = type => {
  console.log(type);
};

const handleBatchClick: MerakXTableInstance["batchClick"] = async params => {
  console.log(params);
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        refresh: true
      });
    }, 500);
  });
};

const handleHanlerClick: MerakXTableInstance["handlerClick"] = async params => {
  console.log(params);
  if (params.type === "details") return false;
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(true);
    }, 500);
  });
};
</script>

<style scoped lang="scss">
.custom_row {
  word-wrap: break-word;
  white-space: wrap;
}
</style>
